import { DicObj } from "../../config/someConfig";
import { Room } from "../room";

export interface FrameClient{
     clientIndex: number;//帧的索引
     uid: number;//角色id
     dir: number; //方向，0不动，1上，2右，3下，4左
     laybomb: number;//0就是不放炸弹，1就是放炸弹
}

export interface FrameServer{
     index: number;//帧的索引
     recvs: Array<FrameClient>;
}

export class FrameSync {
    public static frameTime = 100;//毫秒
    private curIndex: number = 0;
    private sendIndex: number = 0;
    private charNum: number = 2; 
    private index2frameSend: Map<number, FrameServer>;

    public sendFrameCallback: Function;
    public players: DicObj<{ "uid": number, "nickname": string, "headId": number }>;

    constructor(){
        this.index2frameSend = new Map<number, FrameServer>();
    }

    private tick(thisArg: FrameSync){
        if(thisArg.curIndex - thisArg.sendIndex > 1){
            var frameSend = thisArg.index2frameSend.get(thisArg.sendIndex);
            if(frameSend){
                thisArg.index2frameSend.delete(thisArg.sendIndex);
                frameSend.index = thisArg.curIndex;
                if(frameSend.recvs.length == thisArg.charNum){
                    //所有玩家的操作序列收到了，不做任何操作
                }else{
                    var isFind: boolean;
                    for (const key in thisArg.players) {
                        let player =  thisArg.players[key];

                        //没找到，才能下发
                        isFind = false;
                        for (const recv of  frameSend.recvs) {
                            isFind = recv.uid == player.uid;
                            if(isFind)
                                break;
                        }

                        if(!isFind){
                            var fc: FrameClient = {clientIndex: thisArg.sendIndex, uid: player.uid, dir: 0, laybomb: 0};
                            frameSend.recvs.push(fc);
                            console.log("一个人延时了:" + player.uid);
                        }
                    }
                }

                //发送帧frameSend
                thisArg.sendFrameCallback(frameSend);
            }else{
                //两个玩家都网络延时了
                var fs: FrameServer = {index: thisArg.curIndex, recvs: new Array<FrameClient>()};
                for (const key in thisArg.players) {
                    let player = thisArg.players[key];
                    var fc: FrameClient = {clientIndex: thisArg.sendIndex, uid: player.uid, dir: 0, laybomb: 0};
                    fs.recvs.push(fc);
                    console.log("两个人都延时了:" + player.uid);
                }
                //发送帧frameSend
                thisArg.sendFrameCallback(fs);
            }

            //发送完需要自增
            thisArg.sendIndex++;
            thisArg.curIndex++;

            //console.log("我们是Lock Step Sync，大于1帧就需要等待:");
            //我们是Lock Step Sync，大于1帧就需要等待 （todo：改成乐观帧同步Frame Sync 有玩家延时了，不等它）
            return;   
        }
        
        //开始两帧没收到客户端消息，需要强制发
        if(thisArg.curIndex < 2){
            thisArg.sendFrameCallback({index:thisArg.curIndex, recvs: new Array<FrameClient>()});
        }

        thisArg.curIndex++;
        console.log("curIndex:" + thisArg.curIndex);
    }

    private _intervalTag: any;
    public start(){
        this. _intervalTag = setInterval(this.tick, FrameSync.frameTime, this);
    }

    public stop(){
        if(this. _intervalTag){
            clearInterval(this._intervalTag);
            this. _intervalTag = null;
        }
    }

    public input(frameClient: FrameClient){
        if(frameClient.clientIndex < this.sendIndex){
            console.log("==id:" + frameClient.uid + " index:" + frameClient.clientIndex + " 超时");
            return;
        }
        var frameSend = this.index2frameSend.get(frameClient.clientIndex);
        if(!frameSend){
            frameSend = {index: -1, recvs: new Array<FrameClient>()};
            this.index2frameSend.set(frameClient.clientIndex, frameSend)
        }
        frameSend.recvs.push(frameClient);
    }
}